<?php
// Module Body

define('INT_MAX', 4294967296.0);

class CBand {
	var $DST_CLASS = 3;
	var $totalBytes;
	var $classBytes;
	var $startTime;
	var $flushCount;
	var $wasRequest;

	function CBand($file=NULL) {
		$this->__construct($file);
	}

	function __construct($file=NULL) {
		$this->totalBytes = 0;
		$this->classBytes = array();
		$this->startTime = 0;
		$this->flushCount = 0;
		$this->wasRequest = 0;

		if($file!==NULL) {
			return $this->load($file);
		}
	}

	function load($file) {
		if (is_readable($file)) {
			$fp = fopen($file, 'rb');
			$buf = fread($fp, 20+$this->DST_CLASS*8);
			fclose($fp);
			$data = unpack('L2total/L'.($this->DST_CLASS*2).'class/Ltime/'.'lflush/ireq', $buf);

			$this->totalBytes = $this->__compose($data['total1'], $data['total2']);
			for($i = 0; $i < $this->DST_CLASS; ++$i) {
				$this->classBytes[$i] = $this->__compose($data['class'.($i*2+1)], $data['class'.($i*2+2)]);
			}
			$this->startTime = $data['time']; //don't convert for precission
			$this->flushCount = $data['flush'];
			$this->wasRequest = $data['req'];
			return $this;
		} else {
			return false;
		}
	}

	function save($file) {
		if (is_writable($file)) {
			$data = $this->__decompose($this->totalBytes);
			$buf = pack('L2', $data[0], $data[1]);

			for($i = 0; $i < $this->DST_CLASS; ++$i) {
				$data = $this->__decompose($this->classBytes[$i]);
				$buf .=  pack('L2', $data[0], $data[1]);
			}
			$buf .= pack('Lli', $this->startTime, $this->flushCount, $this->wasRequest);

			$fp = fopen($file, 'wb');
			fwrite($fp, $buf);
			fclose($fp);
			return true;
		} else {
			return false;
		}
	}

	function __uint2float($num) {
		$num = floatval($num);

		if($num < 0) {
			$num = INT_MAX + $num;
		}

		return $num;
	}

	function __float2uint($num) {
		if($num >= INT_MAX) {
			$num = INT_MAX - $num;
		}

		return intval($num);
	}

	function __compose($a, $b) {
		//Assume little-endian byte order.
		//Swap total1 and total2 on big endian systems
		return $this->__uint2float($a) + $this->__uint2float($b)*INT_MAX;
	}

	function __decompose($num) {
		return array($this->__float2uint(fmod($num, INT_MAX)),
			$this->__float2uint($num / INT_MAX));
	}
}

function mod_cband_generate_host_conf(&$data) {
	global $cfg;
	unset($search);
	unset($replace);

	// Generate mod_cband configuration
	// open virthost.mod_cband.tpl
	$file = $cfg['basedir']."/httpd/templates/mod_cband.httpd.tpl";
	$mod_cband_conf = stripslashes(file_get_contents($file));

	$search[] = "{SCOREBOARDFILE}";
	$replace[] = $cfg['basedir'].'/httpd/scoreboards/'.$data['host'].'.'.$data['domain'].'.scoreboard';

	$search[] = "{TRANSFER}";
	if ($data['transfer'] > 0) {
		$replace[] = $data['transfer'].'Gi';
	} else {
		$replace[] = ' ';
		$search[] = 'CBandLimit';
		$replace[] = '';
	}

	$search[] = "{BANDWIDTH}";
	if ($data['bandwidth'] > 0) {
		$replace[] = $data['bandwidth'];
		
		$search[] = "{REQUESTS_PER_SECOND}";
		$replace[] = $cfg['mod_cband_rps'];

		$search[] = "{OPEN_CONNECTIONS}";
		$replace[] = $cfg['mod_cband_max_conn'];
	} else {
		$replace[] = '';
		
		$search[] = 'CBandSpeed';
		$replace[] = '';
		
		$search[] = "{REQUESTS_PER_SECOND}";
		$replace[] = '';

		$search[] = "{OPEN_CONNECTIONS}";
		$replace[] = '';
	}

	$mod_cband_conf = str_replace($search, $replace, $mod_cband_conf);

	return $mod_cband_conf;
}

function mod_cband_quota_check(&$data) {

	$dbp = mysql_query("SELECT id, host, domain, FROM domains WHERE type = 'domain'");

	while ($dbp != false && mysql_num_rows($dbp) > 0 && $rowdata = mysql_fetch_array($dbp)) {

		$file = $cfg['basedir'].'/httpd/scoreboards/'.$rowdata['host'].'.'.$rowdata['domain'].'.scoreboard';
		$sb = new CBand($file);
		if (is_object($sb) && is_numeric($sb->totalBytes)) {
			$webtransfer = $sb['totalBytes'];
		} else {
			$webtransfer = 0;
		}
		set_property('transfer_used', $webtransfer, $data['id'], 'transfer_used');

	}
}

function mod_cband_quota_reset(&$data) {

	$dbp = mysql_query("SELECT id, host, domain FROM domains WHERE type = 'domain'");

	while ($dbp != false && mysql_num_rows($dbp) > 0 && $rowdata = mysql_fetch_array($dbp)) {

		$file = $cfg['basedir'].'/httpd/scoreboards/'.$rowdata['host'].'.'.$rowdata['domain'].'.scoreboard';
		$sb = new CBand($file);
		$sb->totalBytes = 0;
		$sb->save($file);

	}
}

function mod_cband_reseller_settings(&$data) {
	global $T;
	if (isset($data['resellerdata']['transfer'])) {
		$val = $data['resellerdata']['transfer'];
	} elseif (isset($data['data']['transfer'])) {
		$val = $data['data']['transfer'];
	}
	if ($data['userdata']['level'] < 2) {
		$value = '<input type="text" name="data[transfer]" size="5" maxlength="255" value="';
		if ($val != -1) {
			$value .= intval($val);
		}
		$value .= '" id="transfer" onchange="document.getElementById(\'transfercheck\').checked = false;">&nbsp;'.$T['gb'].'<input type=checkbox id="transfercheck" name="data[transfer]" value="-1" onclick="document.getElementById(\'transfer\').value = \'\'"';
		if ($val == -1) {
			$value .= ' checked"';
		}
		$value .= '>'.$T['Unlimited'];
	} else {
		$value = (($val == -1) ? $T['Unlimited'] : intval($val));
	}
	$data['entries'][] = Array('name' => $T['Transfer Quota'], 'value' => $value);

	if (isset($data['resellerdata']['bandwidth'])) {
		$val = $data['resellerdata']['bandwidth'];
	} elseif (isset($data['data']['bandwidth'])) {
		$val = $data['data']['bandwidth'];
	}
	if ($data['userdata']['level'] < 2) {
		$value = '<input type="text" name="data[bandwidth]" size="5" maxlength="255" value="';
		if ($val != -1) {
			$value .= intval($val);
		}
		$value .= '" id="bandwidth" onchange="document.getElementById(\'bandwidthcheck\').checked = false;">&nbsp;'.$T['kbps'].'<input type=checkbox id="bandwidthcheck" name="data[bandwidth]" value="-1" onclick="document.getElementById(\'bandwidth\').value = \'\'"';
		if ($val == -1) {
			$value .= ' checked"';
		}
		$value .= '>'.$T['Unlimited'];
	} else {
		$value = (($val == -1) ? $T['Unlimited'] : intval($val));
	}
	$data['entries'][] = Array('name' => $T['Bandwidth'], 'value' => $value);
}

function mod_cband_domain_settings(&$data) {
	global $T;
	if (isset($data['domaindata']['transfer'])) {
		$val = $data['domaindata']['transfer'];
	} elseif (isset($data['data']['transfer'])) {
		$val = $data['data']['transfer'];
	}
	if ($data['userdata']['level'] < 3) {
		$value = '<input type="text" name="data[transfer]" size="5" maxlength="255" value="';
		if ($val != -1) {
			$value .= intval($val);
		}
		$value .= '" id="transfer" onchange="document.getElementById(\'transfercheck\').checked = false;">&nbsp;'.$T['gb'].'&nbsp;<input type=checkbox id="transfercheck" name="data[transfer]" value="-1" onclick="document.getElementById(\'transfer\').value = \'\'"';
		if ($val == -1) {
			$value .= ' checked"';
		}
		$value .= '>'.$T['Unlimited'];
	} else {
		$value = (($val == -1) ? $T['Unlimited'] : intval($val));
	}
	$data['entries'][] = Array('name' => $T['Transfer Quota'], 'value' => $value);

	if (isset($data['domaindata']['bandwidth'])) {
		$val = $data['domaindata']['bandwidth'];
	} elseif (isset($data['data']['bandwidth'])) {
		$val = $data['data']['bandwidth'];
	}
	if ($data['userdata']['level'] < 3) {
		$value = '<input type="text" name="data[bandwidth]" size="5" maxlength="255" value="';
		if ($val != -1) {
			$value .= intval($val);
		}
		$value .= '" id="bandwidth" onchange="document.getElementById(\'bandwidthcheck\').checked = false;">&nbsp;'.$T['kbps'].'&nbsp;<input type=checkbox id="bandwidthcheck" name="data[bandwidth]" value="-1" onclick="document.getElementById(\'bandwidth\').value = \'\'"';
		if ($val == -1) {
			$value .= ' checked"';
		}
		$value .= '>'.$T['Unlimited'];
	} else {
		$value = (($val == -1) ? $T['Unlimited'] : intval($val));
	}
	$data['entries'][] = Array('name' => $T['Bandwidth'], 'value' => $value);
}

function mod_cband_get_infotable(&$ret) {
	global $T;
	$current = Array('label' => $T['Transfer Quota'], 'fieldname' => 'transfer', 'url' => '');
	$ret['entries'][] = $current;

	$current = Array('label' => $T['Bandwidth'], 'fieldname' => 'bandwidth', 'url' => '');
	$ret['entries'][] = $current;
}

function  mod_cband_template(&$ret) {
	global $cfg;

	$template['title'] = 'mod_cband';
	$template['servicename'] = 'httpd';
	$template['active'] = true;
	$template['file'][] = array('filename' => 'mod_cband');

	$ret[] = $template;

}

function bandwidth_set(&$data) {
	set_property('bandwidth', $data['bandwidth'], $data['id'], 'bandwidth');
}

function transfer_set(&$data) {
	set_property('transfer', $data['transfer'], $data['id'], 'transfer');
}

function bandwidth_fetch(&$data) {
	if ($data['type'] == 'reseller') {
		$where = substr($data['where'],0,5);
	} else {
		$where = $data['where'];
	}
	$bandwidth = get_property('bandwidth', $where, 'bandwidth');
	$data['name'][] = 'bandwidth';
	$data['value'][] = $bandwidth;
	return true;
}

function transfer_fetch(&$data) {
	if ($data['type'] == 'reseller') {
		$where = substr($data['where'],0,5);
	} else {
		$where = $data['where'];
	}
	$transfer = get_property('transfer', $where, 'transfer');
	$data['name'][] = 'transfer';
	$data['value'][] = $transfer;
	return true;
}

function bandwidth_fetch_alloc(&$data) {
	$where = $data['where'];
	if ($where == 0) {
		$SQL = 'SELECT max(properties.value) as bandwidth FROM properties WHERE properties.name = "bandwidth"';
		if ($res = mysql_query($SQL)) {
			if (mysql_num_rows($res)) {
				$row = mysql_fetch_array($res);
				$bandwidth = $row['bandwidth'];
			}
		}
	} elseif (strlen($where) == 5) {
		$SQL = 'SELECT max(properties.value) as bandwidth FROM properties inner join domains ON properties.id = domains.id WHERE domains.owner = '.$where.' AND properties.value != -1 AND properties.name = "bandwidth"';
		if ($res = mysql_query($SQL)) {
			if (mysql_num_rows($res)) {
				$row = mysql_fetch_array($res);
				$bandwidth = $row['bandwidth'];
			}
		}
	} else {
		$bandwidth = get_property('bandwidth', $where, 'bandwidth');
	}
	$data['name'] = 'bandwidth';
	$data['value'] = $bandwidth;
	return true;
}

function transfer_fetch_alloc(&$data) {
	$where = $data['where'];
	if ($where == 0) {
		$SQL = 'SELECT sum(properties.value) as transfer FROM properties WHERE properties.name = "transfer"';
		if ($res = mysql_query($SQL)) {
			if (mysql_num_rows($res)) {
				$row = mysql_fetch_array($res);
				$transfer = $row['transfer'];
			}
		}
	} elseif (strlen($where) == 5) {
		$SQL = 'SELECT sum(properties.value) as transfer FROM properties inner join domains ON properties.id = domains.id WHERE domains.owner = '.$where.' AND properties.value != -1 AND properties.name = "transfer"';
		if ($res = mysql_query($SQL)) {
			if (mysql_num_rows($res)) {
				$row = mysql_fetch_array($res);
				$transfer = $row['transfer'];
			}
		}
	} else {
		$transfer = get_property('transfer', $where, 'transfer');
	}
	$data['name'] = 'transfer';
	$data['value'] = $transfer;
	return true;
}

function bandwidth_fetch_total(&$data) {
	$where = $data['where'];
	if ($where == 0) {
		$SQL = 'SELECT max(properties.value) as bandwidth FROM properties WHERE properties.name = "bandwidth"';
		if ($res = mysql_query($SQL)) {
			if (mysql_num_rows($res)) {
				$row = mysql_fetch_array($res);
				$bandwidth = $row['bandwidth'];
			}
		}
	} elseif (strlen($where) == 5) {
		$SQL = 'SELECT max(properties.value) as bandwidth FROM properties inner join domains ON properties.id = domains.id WHERE domains.owner = '.$where.' AND properties.value != -1 AND properties.name = "bandwidth"';
		if ($res = mysql_query($SQL)) {
			if (mysql_num_rows($res)) {
				$row = mysql_fetch_array($res);
				$bandwidth = $row['bandwidth'];
			}
		}
	} else {
		$bandwidth = get_property('bandwidth', $where, 'bandwidth');
	}
	$data['name'] = 'bandwidth';
	$data['value'] = $bandwidth;
	return true;
}

function transfer_fetch_total(&$data) {
	$where = $data['where'];
	if ($where == 0) {
		$SQL = 'SELECT sum(properties.value) as transfer FROM properties WHERE properties.value != -1 AND properties.name = "transfer"';
		if ($res = mysql_query($SQL)) {
			if (mysql_num_rows($res)) {
				$row = mysql_fetch_array($res);
				$transfer = $row['transfer'];
			}
		}
	} elseif (strlen($where) == 5) {
		$SQL = 'SELECT sum(properties.value) as transfer FROM properties inner join domains ON properties.id = domains.id WHERE domains.owner = '.$where.' AND properties.value != -1 AND properties.name = "transfer"';
		if ($res = mysql_query($SQL)) {
			if (mysql_num_rows($res)) {
				$row = mysql_fetch_array($res);
				$transfer = $row['transfer'];
			}
		}
	} else {
		$transfer = get_property('transfer', $where, 'transfer');
	}
	$data['name'] = 'transfer';
	$data['value'] = $transfer;
	return true;
}

function transfer_check(&$data) {
	$transfer = get_property('transfer', $data['id'], 'transfer');
	if ($transfer == $data['transfer']) {
		return '';
	} else {
		return 'change';
	}
}

function bandwidth_check(&$data) {
	$bandwidth = get_property('bandwidth', $data['id'], 'bandwidth');
	if ($bandwidth == $data['bandwidth']) {
		return '';
	} else {
		return 'change';
	}
}

function transfer_domain_check(&$data) {
	global $T;
	$res =  Array();
	$transfer = get_property('transfer', $data['id'], 'transfer');
	if ($transfer != '' && $transfer != $data['transfer']) {
		$res['change'] = 'change';
	}
	$reseller_total = fetchdata('transfer','reseller', substr($data['id'],0,5));
	$reseller_total = $reseller_total['transfer'];
	$reseller_alloc = fetchdata('transfer','alloc', substr($data['id'],0,5));
	$reseller_alloc = $reseller_alloc['transfer'];
	$domain_alloc = fetchdata('transfer','domain', $data['id']);
	$domain_alloc = $domain_alloc['transfer'];
	$available_transfer = $reseller_total - $reseller_alloc + $domain_alloc;
	if (($reseller_total != -1) && (($data['transfer'] > $available_transfer) || $data['transfer'] == -1)) {
		$res['error'] = $T['err']['Not enough transfer.'];
	}
	return $res;
}

function bandwidth_domain_check(&$data) {
	global $T;
	$res =  Array();
	$bandwidth = get_property('bandwidth', $data['id'], 'bandwidth');
	if ($bandwidth != '' && $bandwidth != $data['bandwidth']) {
		$res['change'] = 'change';
	}
	$reseller_total = fetchdata('bandwidth','reseller', substr($data['id'],0,5));
	$reseller_total = $reseller_total['bandwidth'];
	$available_bandwidth = $reseller_total;
	if (($reseller_total != -1) && (($data['bandwidth'] > $available_bandwidth) || $data['bandwidth'] == -1)) {
		$res['error'] = $T['err']['Not enough bandwidth.'];
	}
	return $res;
}

function mod_cband_add_lang(&$data) {
	global $T;
	switch($data['lang']) {
		default:
			$T['mod_cband service'] = 'mod_cband';
			$T['mod_cband'] = 'Mod CBand';
			/* Why is this here?
			$T['mod_cband']['{}']		= '';
			$T['mod_cband']['{}']		= '';
			$T['mod_cband']['{}']		= '';
			$T['mod_cband']['{}']		= '';
			$T['mod_cband']['{}']		= '';*/

			$T['Transfer Quota'] = 'Transfer Quota';
			$T['err']['Not enough transfer.'] = 'Not enough transfer.';
			$T['Bandwidth'] = 'Bandwidth';
			$T['err']['Not enough bandwidth.'] = 'Not enough bandwidth.';
			break;
	}
}

function mod_cband_add_cfg(&$cfg) {
	$cfg['mod_cband_tpl'] = true;  // Enable Template
	$cfg['mod_cband_rps'] = 50; // Maximum requests per second (per Virual tHost)
	$cfg['mod_cband_max_conn'] = 10; // Maximum connections (per remote user)
}
?>